import requests
import json
import os
import time
from publib import setup_logger, get_logger

cur_file = os.path.basename(__file__).split(".")[0]
logger = get_logger(__name__)

music_bak_file = "backup.json"
music_path = "F:/storage/music"

def get_music_list():
    music_list = []
    music = []
    with open(music_bak_file, "r", encoding="utf-8") as f:
        music = json.load(f)
    
    for sheet in music.get("musicSheets", []):
        for i in sheet.get("musicList", []):
            name = f"{i.get('title')}-{i.get('artist')}"
            if name not in music_list:
                music_list.append(name)

    return music_list

def is_name_same(name1, name2):
    name1 = name1.replace(" ", "").replace("/", ",").replace("&", ",").replace("、", ",").replace("（", "(").replace("）", ")").replace("ive版", "ive")
    name2 = name2.replace(" ", "").replace("/", ",").replace("&", ",").replace("、", ",").replace("（", "(").replace("）", ")").replace("ive版", "ive")
    song1 = name1.split("-")[0]
    song2 = name2.split("-")[0]
    singer1 = name1.split("-")[1].split(",")
    singer2 = name2.split("-")[1].split(",")
    if (song1 == song2):
        for i in singer1:
            if i in singer2:
                return True
    return False

def _get_music_url_netease(src="", name = "", id = ""):
    if (src != "wy" or id == ""):
        return ""
    music_url = ""
    api = "https://sdkapi.hhlqilongzhu.cn/api/dgMusic_wyy/"
    url = f"{api}?key=DragonA09D453B5BD84C8FE367C88F09340C54&id={id}&n=1&type=json&br=3"
    # print(url)
    r = requests.get(url)
    # print(r.json())
    if (r.status_code == 200):
        song = r.json().get("title", "")
        singer = r.json().get("singer", "")
        url = r.json().get("music_url", "")
        if ("http" in url):
            music_url = url
    return music_url

def _get_music_url_qq_by_name(src="", name = "", id = ""):
    music_url = ""
    api = "https://sdkapi.hhlqilongzhu.cn/api/QQmusic"
    url = f"{api}?key=DragonA09D453B5BD84C8FE367C88F09340C54&msg={name}&n=1&type=json&br=1"
    r = requests.get(url)
    if (r.status_code == 200):
        data = r.json().get("data", {})
        song = data.get("song_name", "")
        singer = data.get("song_singer", "")
        if (is_name_same(name, f"{song}-{singer}")):
            music_url = data.get("music_url", "")
    return music_url

def _get_music_url_netease_by_name(src="", name = "", id = ""):
    music_url = ""
    api = "https://sdkapi.hhlqilongzhu.cn/api/dgMusic_wyy"
    url = f"{api}?key=DragonA09D453B5BD84C8FE367C88F09340C54&gm={name}&n=1&type=json&br=3"
    r = requests.get(url)
    if (r.status_code == 200):
        song = r.json().get("title", "")
        singer = r.json().get("singer", "")
        if (is_name_same(name, f"{song}-{singer}")):
            music_url = r.json().get("music_url", "")
    return music_url

def _get_music_url_kuwo_by_name(src="", name = "", id = ""):
    music_url = ""
    api = "https://sdkapi.hhlqilongzhu.cn/api/dgMusic_kuwo"
    url = f"{api}?key=DragonA09D453B5BD84C8FE367C88F09340C54&msg={name}&n=1&type=json&br=1"
    r = requests.get(url)
    # print(f"kw {r.text}")
    if (r.status_code == 200):
        song = r.json().get("song_name", "")
        singer = r.json().get("song_singer", "")
        if (is_name_same(name, f"{song}-{singer}")):
            music_url = r.json().get("flac_url", "")
    return music_url

def _get_music_url_kugou_by_name(src="", name = "", id = ""):
    music_url = ""
    api = "https://sdkapi.hhlqilongzhu.cn/api/dgMusic_kugou"
    url = f"{api}?key=DragonA09D453B5BD84C8FE367C88F09340C54&msg={name}&n=1&type=json"
    r = requests.get(url)
    # print(f"kg {r.text}")
    if (r.status_code == 200):
        song = r.json().get("title", "")
        singer = r.json().get("singer", "")
        if (is_name_same(name, f"{song}-{singer}")):
            music_url = r.json().get("music_url", "")
    return music_url

def get_music_url(src = "", name = "", id = ""):
    apis = [
        _get_music_url_netease,
        _get_music_url_qq_by_name,
        _get_music_url_netease_by_name,
        _get_music_url_kuwo_by_name,
        _get_music_url_kugou_by_name,
    ]
    for api in apis:
        try:
            music_url = api(src, name, id)
        except Exception as e:
            logger.error(f"get music url error: {e}, {api.__name__}")
            continue
        if (len(music_url) > 0 and ("mp3" in music_url or "flac" in music_url)):
            return music_url
        else:
            time.sleep(2)
    return ""

def download_music(url, save_path):
    if ("mp3" in url):
        save_path += ".mp3"
    elif ("flac" in url):
        save_path += ".flac"
    else:
        logger.error(f"unknown format: {url}")
        return False
    try:
        print(f"start download {os.path.basename(save_path)}")
        r = requests.get(url, stream=True)
        r.raise_for_status()  # 检查请求是否成功
        with open(save_path, 'wb') as file:
            for chunk in r.iter_content(chunk_size=8192):
                if chunk:  # 过滤掉 keep-alive 新块
                    file.write(chunk)
        logger.info(f"文件已下载到: {save_path}")
        return True
    except requests.exceptions.RequestException as e:
        print(f"下载失败: {e}")
        return False
    
def is_music_exist(name):
    for i in os.listdir(music_path):
        i = os.path.splitext(i)[0]
        if (is_name_same(name, i)):
            return True
    return False

# name={song-singer}
def dl_music(src, name, id, mid=""):
    ret = True
    if not is_music_exist(name):
        url = get_music_url(src, name, id)
        ret = -1
        if (len(url) > 0):
            ret = download_music(url, f"{music_path}/{name}")
        if (ret != True):
            print(f"{name} 下载失败")
            ret = False
    return ret

if __name__ == "__main__":
    setup_logger(f"logs/{cur_file}.log")
    src = "wy"
    name = "这世界那么多人-四熹丸子"
    id = "349892"
    ret = dl_music(src, name, id)
    print(f"{src} {name} {id} result: {ret}")

    # src = ""
    # name = "我的心好冷-刘佳"
    # id = ""
    # ret = dl_music(src, name, id)
    # print(f"{src} {name} {id} result: {ret}")
    pass
